#define _GNU_SOURCE
#include "daemon_sub_process.h"
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <sys/reboot.h>
#include <signal.h>
#include "log/log.h"

SubProcess *daemon_sub_process_init(char *cmd_param)
{
    SubProcess *sp = (SubProcess *)malloc(sizeof(SubProcess));
    sp->cmd_param = cmd_param;
    sp->fail_count = 0;
    sp->pid = 0;
    return sp;
}

int daemon_sub_process_start(SubProcess *sp)
{
    //检查进程是否在运行
    int status = 0;
    if (sp->pid > 0 && waitpid(sp->pid, &status, WNOHANG) == 0)
    {
        log_debug("子进程【%s】已存在,请勿重复启动",sp->cmd_param);
        return 0;
    }
    //如果子进程是异常退出，则设置失败次数，超过最大值则重启
    if (status != 0)
    {
        sp->fail_count++;
        if(sp->fail_count > MAX_FAIL_COUNT)
        {
            log_debug("子进程异常退出，重启子进程");
            reboot(RB_AUTOBOOT);
        }
    }
    //进程当前没有运行，则创建子进程
    sp->pid = fork();
    if (sp->pid == 0)
    {
        //说明当前是子进程，运行当前的对应模块 app/ota
        char *argv[] = {EXE_PATH, sp->cmd_param, NULL};
        execve(EXE_PATH, argv, NULL);
        //结束当前子进程（execve成功不会往下执行，失败就结束进程）
        _exit(EXIT_FAILURE);
    }
    return 0;
}

void daemon_sub_process_stop(SubProcess *sp)
{
    // 结束进程
    kill(sp->pid, SIGTERM);
    //等待进程结束
    waitpid(sp->pid, NULL, 0);
    free(sp);
}
